package com.kj.tms.system.service.org.serviceImpl;

import com.kj.tms.common.bean.dao.BaseMapper;
import com.kj.tms.common.bean.dto.Pager;
import com.kj.tms.common.bean.dto.ReturnData;
import com.kj.tms.common.bean.dto.TreeData;
import com.kj.tms.common.bean.service.BaseService;
import com.kj.tms.common.bean.session.SessionManager;
import com.kj.tms.common.utils.StringUtil;
import com.kj.tms.common.utils.constant.Consts;
import com.kj.tms.common.utils.uuid.IdGen;
import com.kj.tms.pri.system.org.dto.OrgDto;
import com.kj.tms.pri.system.org.service.OrgService;
import com.kj.tms.pri.system.user.dto.UserDto;
import com.kj.tms.pri.system.user.dto.UserOrgDto;
import com.kj.tms.pri.system.user.dto.UserOrgRoleDto;
import com.kj.tms.pri.system.user.service.UserOrgRoleService;
import com.kj.tms.pri.system.user.service.UserOrgService;
import com.kj.tms.system.service.org.dao.OrgMapper;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @ProjectName:
 * @Package: com.hongtu.tms.system.org.service.impl
 * @ClassName: OrgServiceImpl
 * @Description: 组织机构OrgServiceImpl
 * @Author: 董世栋
 * @CreateDate:
 * @UpdateUser:
 * @UpdateDate:
 * @UpdateRemark:
 * @Version: 1.0
 * Copyright: 北京宏图天安 Copyright (c) 2017
 */
@Service
public class OrgServiceImpl extends BaseService<OrgDto> implements OrgService {

    @Autowired
    private OrgMapper orgMapper;

    @Autowired
    private SessionManager sessionManager;

    @Autowired
    private UserOrgService userOrgService;

    @Autowired
    private UserOrgRoleService userOrgRoleService;

    @Override
    public BaseMapper<OrgDto> getMapper() {
        return orgMapper;
    }

    /**
     * @param userId
     * @return List<OrgDto>
     * @throws
     * @method queryOrgByUser
     * @description 根据用户查询机构
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public List<OrgDto> queryOrgByUser(@RequestParam("userId")String userId) {
        return orgMapper.queryOrgByUser(userId);
    }

    /**
     * @param model
     * @return List<TreeData>
     * @throws
     * @method getTreeData
     * @description 获取根据条件查询机构树（只针对名称模糊查询）
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public List<TreeData> getTreeData(@RequestBody(required = false)OrgDto model) {
        model.setDelMark(Consts.DEL_MARK_0);

        UserDto dto = (UserDto) sessionManager.getAttribute(Consts.USER);
        String curUserOrgCode = dto.getCurUserOrgCode();
        model.setOrgCode(curUserOrgCode);
//      List<TreeData> results = queryDirectChildrenByList(model);
        List<TreeData> results = orgMapper.getTreeDataByOrgName(model);
        return results;
    }


    /**
     * @param model
     * @return List<TreeData>
     * @throws
     * @method getDirectChildrenTreeData
     * @description 获取根据条件查询机构树
     * @author 黄冬冬
     * @version 1.0
     * @date
     */
    @Override
    public List<TreeData> getDirectChildrenTreeData(@RequestBody(required = false)OrgDto model) {

        model.setDelMark(Consts.DEL_MARK_0);
        UserDto dto = (UserDto) sessionManager.getAttribute(Consts.USER);
        String curUserOrgCode = dto.getCurUserOrgCode();
        if ("".equals(model.getOrgCode()) || StringUtil.isNull(model.getOrgCode())) {
            model.setOrgCode(curUserOrgCode);
            model.setIsParent("true");
        }
        List<TreeData> results = queryDirectChildrenByList(model);
        return results;
    }

    /**
     * @param userCode
     * @return List<TreeData>
     * @throws
     * @method getTreeData
     * @description 根据用户编码查询机构树
     * @Date: 2017年11月30日 11:16
     * @Author:wangguoqing
     * @version: 2017年11月30日 11:16
     */
    @Override
    public List<TreeData> getTreeDataByUserCode(@RequestParam("userCode") String userCode) {
        Map<String, Object> map = new HashMap<>();
        map.put("userCode", userCode);
        UserDto dto = (UserDto) sessionManager.getAttribute(Consts.USER);
        String curUserOrgCode = dto.getCurUserOrgCode();
        map.put("curUserOrgCode", curUserOrgCode);
        List<TreeData> results = orgMapper.queryByUserCodeList(map);
        return results;
    }

    /**
     * @param model
     * @return List<TreeData>
     * @throws
     * @method queryByList
     * @description 根据 OrgDto传值条件查询机构信息,包含查下级所有机构
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public List<TreeData> queryByList(@RequestBody(required = false)OrgDto model) {

        UserDto user = (UserDto) sessionManager.getAttribute(Consts.USER);
        if (user != null) {
            model.setOrgCode(user.getCurUserOrgCode());
        }

        return orgMapper.queryByList(model);
    }

    /**
     * @param model
     * @return List<TreeData>
     * @throws
     * @method queryDirectChildrenByList
     * @description 根据 OrgDto传值条件查询机构信息,只包含直接下级
     * @author 黄冬冬
     * @version 1.0
     * @date
     */
    @Override
    public List<TreeData> queryDirectChildrenByList(@RequestBody(required = false)OrgDto model) {
        return orgMapper.queryDirectChildrenByList(model);
    }

    /**
     * @param model
     * @return List<OrgDto>
     * @throws
     * @method listByOrg
     * @description 根据 OrgDto传值条件查询机构信息
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public List<OrgDto> listByOrg(@RequestBody(required = false)OrgDto model) {
        return orgMapper.listByOrg(model);
    }

    /**
     * @param
     * @return
     * @throws
     * @method [queryOrgByList]
     * @description [模糊匹配查询机构数据到列表]
     * @author 王国庆
     * @version 1.0
     * @date 2017年12月28日 14:22
     */
    @Override
    public List<OrgDto> queryOrgByList(@RequestBody(required = false)OrgDto orgDto) {
        return orgMapper.queryOrgByList(orgDto);
    }

    /**
     * @param orgDto
     * @return List<OrgDto>
     * @throws
     * @method queryOrgByConditions
     * @description 根据dto条件查全部
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public OrgDto getByConditions(@RequestBody(required = false)OrgDto orgDto) {
        return orgMapper.getByConditions(orgDto);
    }

    /**
     * @param model
     * @return Pager
     * @throws
     * @method listByPage
     * @description 分页查询组织信息
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public Pager listByPage(@RequestBody(required = false)OrgDto model) {

        return super.selectPage(model);
    }

    /**
     * @param dto
     * @return OrgDto
     * @throws
     * @method addDto
     * @description 添加组织
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public ReturnData insertDto(@RequestBody(required = false)OrgDto dto) {
        ReturnData rtn = new ReturnData();
        //检查机构编码是否重复
        rtn = listHaveOrg(dto.getOrgCode(), dto.getId());
        if (rtn.getCode().equals(Consts.ERROR)) {
            return rtn;
        }
        //设置组织基础信息
        dto = setOrg(dto);
        orgMapper.insertDto(dto);
        rtn.setCode(Consts.SUCCESS);
        return rtn;
    }

    /**
     * @param dto
     * @return OrgDto
     * @throws
     * @method setOrg
     * @description 设置组织基础信息
     * @author 董世栋
     * @version 1.0
     * @date
     */
    private OrgDto setOrg(OrgDto dto) {
        //保存组织信息
        UserDto user = (UserDto) sessionManager.getAttribute(Consts.USER);
        if (StringUtil.isNotNull(user)) {
            if (StringUtils.isBlank(dto.getId())) {
                dto.setCreateUser(user.getUserId());
            }
        }
        dto = setLeaveAndPcodeSet(dto);
        dto.setPcode(dto.getSjcode());
        dto.setValidMark(Consts.VALID_MARK_1);
        dto.setDelMark(Consts.VALID_MARK_0);
        dto.setId(IdGen.getId());
        dto.setCreateTime(new Date());
        return dto;
    }

    /**
     * @param dto
     * @return OrgDto
     * @throws
     * @method setOrg
     * @description 设置组织级别和PcodeSet
     * @author 董世栋
     * @version 1.0
     * @date
     */
    private OrgDto setLeaveAndPcodeSet(OrgDto dto) {
        //pcodeSet赋值
        OrgDto fjDto = orgMapper.getOrgByOrgCode(dto.getSjcode());
        if (StringUtil.isNull(fjDto)) {
            //设置第二级子节点
            dto.setPcodeSet(dto.getSjcode() + "," + dto.getOrgCode());
            dto.setOrgLevel((short) 2);
        } else {
            if (StringUtil.isNotNull(fjDto.getOrgLevel())) {
                dto.setOrgLevel((short) (fjDto.getOrgLevel() + 1));
            }
            if (fjDto.getPcodeSet() != null) {
                dto.setPcodeSet(fjDto.getPcodeSet() + "," + dto.getOrgCode());
            } else {
                dto.setPcodeSet(fjDto.getOrgCode());
            }
        }
        return dto;
    }

    /**
     * @param dto
     * @return Map
     * @throws
     * @method updateBySelective
     * @description 更新组织
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public ReturnData updateBySelective(@RequestBody(required = false)OrgDto dto) {
        ReturnData rtn = new ReturnData();
        UserDto user = (UserDto) sessionManager.getAttribute(Consts.USER);
        if (StringUtil.isNotNull(user)) {
            dto.setUpdateUser(user.getUserId());
            dto.setUpdateTime(new Date());
        }
        //检查机构编码是否重复
        rtn = listHaveOrg(dto.getOrgCode(), dto.getId());
        if (rtn.getCode().equals(Consts.ERROR)) {
            return rtn;
        }
        this.orgMapper.updateBySelective(dto);
        return rtn;
    }

    /**
     * @param dto
     * @return null
     * @throws
     * @method updateByValidMark
     * @description 是否启用
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public void updateByValidMark(@RequestBody(required = false)OrgDto dto) {
        UserDto user = (UserDto) sessionManager.getAttribute(Consts.USER);
        if (StringUtil.isNotNull(user)) {
            dto.setUpdateUser(user.getUserId());
            dto.setUpdateTime(new Date());
        }
        this.orgMapper.updateBySelective(dto);
    }

    /**
     * @param dto
     * @return null
     * @throws
     * @method toDeleteOrg
     * @description 删除
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public ReturnData deleteOrg(@RequestBody(required = false)OrgDto dto) {
        ReturnData rtn = new ReturnData();
        //是否该机构已经创建下级机构
        OrgDto pOrgDto = new OrgDto();
        pOrgDto.setOrgCode(dto.getOrgCode());
        List<TreeData> orgDtos = this.queryDirectChildrenByList(pOrgDto);

        if (StringUtil.isNotNull(orgDtos) && orgDtos.size() > 1) {
            rtn.setCode(Consts.ERROR);
            rtn.setMsg("该机构已经创建下级机构，删除失败");
            return rtn;
        }

        //该机构是否分配人员
        List<UserOrgRoleDto> userOrgRoleDtos = this.userOrgRoleService.listUserOrgRoleByOrgCode(dto.getOrgCode());
        if (StringUtil.isNotNull(userOrgRoleDtos)) {
            rtn.setCode(Consts.ERROR);
            rtn.setMsg("该机构下人员存在权限，删除失败，请先删除人员权限");
            return rtn;
        }

        //该机构是否分配人员
        List<UserOrgDto> userDtos = this.userOrgService.listByOrgCode(dto.getOrgCode());
        if (StringUtil.isNotNull(userDtos)) {
            rtn.setCode(Consts.ERROR);
            rtn.setMsg("该机构下存在人员，删除失败，请先删除人员");
            return rtn;
        }

        UserDto user = (UserDto) sessionManager.getAttribute("user");
        if (StringUtil.isNotNull(user)) {
            dto.setUpdateUser(user.getUserId());
            dto.setUpdateTime(new Date());
        }

        this.orgMapper.deleteOrg(dto);
        rtn.setCode(Consts.SUCCESS);
        return rtn;
    }

    /**
     * @param orgCode
     * @return Map
     * @throws
     * @method listHaveOrg
     * @description 检查机构编码是否重复
     * @author 董世栋
     * @version 1.0
     * @date
     */
    private ReturnData listHaveOrg(String orgCode, String id) {
        ReturnData rtn = new ReturnData();
        //查询orgCode是否重复
        OrgDto havecodeDto = new OrgDto();
        havecodeDto.setOrgCode(orgCode);
        List<OrgDto> orgDtoList = orgMapper.listByOrgAll(havecodeDto);
        if (StringUtil.isNotNull(orgDtoList) && orgDtoList.size() > 0) {
            //id不为空，修改
            if (StringUtil.isNotNull(id)) {
                if (!id.equals(orgDtoList.get(0).getId())) {
                    rtn = getRtnMsg(Consts.ERROR);
                } else {
                    //id相同
                    //查询本下级组织
                    List<OrgDto> havaOrgDtoList = orgMapper.listByOrgCodes(orgCode);
                    if (havaOrgDtoList.size() == 1) {
                        //不存在下级
                        rtn = getRtnMsg(Consts.SUCCESS);
                    } else if (orgCode.equals(orgDtoList.get(0).getOrgCode())) {
                        //存在下级，orgCode没变，可以修该
                        rtn = getRtnMsg(Consts.SUCCESS);
                    } else {
                        rtn = getRtnMsg(null);
                    }
                }
            } else if (orgCode.equals(orgDtoList.get(0).getOrgCode())) {
                //id为空，添加
                rtn = getRtnMsg(Consts.ERROR);
            } else {
                rtn = getRtnMsg(Consts.SUCCESS);
            }
        } else if (StringUtil.isNotNull(id)) {
            havecodeDto.setId(id);
            List<OrgDto> haveOrgDtoList = orgMapper.listByOrgAll(havecodeDto);
            if (StringUtil.isNotNull(haveOrgDtoList)) {
                List<OrgDto> havaOrgDtoList = orgMapper.listByOrgCodes(haveOrgDtoList.get(0).getOrgCode());
                if (havaOrgDtoList.size() == 1) {
                    //不存在下级
                    rtn = getRtnMsg(Consts.SUCCESS);
                } else if (orgCode.equals(orgDtoList.get(0).getOrgCode())) {
                    //存在下级，orgCode没变，可以修该
                    rtn = getRtnMsg(Consts.SUCCESS);
                } else {
                    rtn = getRtnMsg(null);
                }
            } else {
                rtn = getRtnMsg(Consts.SUCCESS);
            }
        } else {
            //不重复
            rtn = getRtnMsg(Consts.SUCCESS);
        }
        return rtn;
    }

    /**
     * @param isSuccess
     * @return ReturnData
     * @throws
     * @method getRtnMsg
     * @description 设置返回信息
     * @author 董世栋
     * @version 1.0
     * @date
     */
    private ReturnData getRtnMsg(String isSuccess) {
        ReturnData rtn = new ReturnData();
        if (isSuccess.equals(Consts.SUCCESS)) {
            rtn.setCode(Consts.SUCCESS);
            rtn.setMsg("保存成功！");
        } else if (isSuccess.equals(Consts.ERROR)) {
            rtn.setCode(Consts.ERROR);
            rtn.setMsg("保存失败，构编码重复！");
        } else {
            rtn.setCode(Consts.ERROR);
            rtn.setMsg("保存失败，该机构下存在下级机构，不允许修改组织编码！");
        }
        return rtn;
    }

    /**
     * @param orgCode
     * @return OrgDto
     * @throws
     * @method getOrgByOrgCode
     * @description 根据OrgCode获取组织信息
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public OrgDto getOrgByOrgCode(@RequestParam("orgCode") String orgCode) {
        return orgMapper.getOrgByOrgCode(orgCode);
    }

    /**
     * @param orgCode
     * @return orgName
     * @throws
     * @method getOrgNameByOrgCode
     * @description 根据OrgCode获取组织信息
     * @author 董世栋
     * @version 1.0
     * @date
     */
    @Override
    public String getOrgNameByOrgCode(@RequestParam("orgCode") String orgCode) {
        return orgMapper.getOrgNameByOrgCode(orgCode);
    }
    /**
    * @Method listByOrgCodes
    * @Param
    * @Return
    * @Exception
    * @Description [     通过orgCode查询本机构以及下级机构-]
    * @Author      yangruidong
    * @Version     1.0
    * @Date        2018/5/31 21:19
    */
    @Override
    public List<OrgDto> listByOrgCodes(@RequestParam("orgCode") String orgCode) {
        return orgMapper.listByOrgCodes(orgCode);
    }

    /**
    * @Method      listByOrgCode
    * @Param
    * @Return
    * @Exception
    * @Description [通过id查询本机构以及下级机构得纳税主体-]
    * @Author      yangruidong
    * @Version     1.0
    * @Date        2018/5/31 21:22
    */
    @Override
    public List<OrgDto> listByOrgCode(@RequestParam("orgCode") String orgCode,
                                      @RequestParam("taxCode")String taxCode,
                                      @RequestParam("period")String period) throws Exception{
        return orgMapper.listByOrgCode(orgCode,taxCode,period);
    }

    /**
    * @Method listByTaxPayerCodes
    * @Param
    * @Return
    * @Exception
    * @Description [通过ids批量查询-纳税主体]
    * @Author      yangruidong
    * @Version     1.0
    * @Date        2018/5/31 21:30
    */
    @Override
    public List<OrgDto> listByTaxPayerCodes(@RequestParam("orgCode") List orgCode) {
        return orgMapper.listByTaxPayerCodes(orgCode);
    }

    /**
    * @Method listByTaxPayer
    * @Param
    * @Return
    * @Exception
    * @Description [通过纳税主体查询]
    * @Author      yangruidong
    * @Version     1.0
    * @Date        2018/5/31 21:31
    */
    @Override
    public List<OrgDto> listByTaxPayer(@RequestParam("orgCode")String[] orgCode) {
        return orgMapper.listByTaxPayer(orgCode);
    }


}
